package com.yugao.fintech.draper.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yugao.fintech.draper.admin.convert.DictItemConvert;
import com.yugao.fintech.draper.admin.entity.SysDict;
import com.yugao.fintech.draper.admin.entity.SysDictItem;
import com.yugao.fintech.draper.admin.mapper.DictItemMapper;
import com.yugao.fintech.draper.admin.mapper.DictMapper;
import com.yugao.fintech.draper.admin.param.DictItemDTO;
import com.yugao.fintech.draper.admin.param.DictItemExistsDTO;
import com.yugao.fintech.draper.admin.param.DictItemQuery;
import com.yugao.fintech.draper.admin.service.DictItemService;
import com.yugao.fintech.draper.core.enums.DictTypeEnum;
import com.yugao.fintech.draper.core.exception.BaseException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;

@Slf4j
@Service
public class DictItemServiceImpl implements DictItemService {
	@Autowired
	private DictItemMapper dictItemMapper;
	@Autowired
	private DictMapper dictMapper;

	@Override
	public IPage<DictItemDTO> pageQuery(DictItemQuery dictItemQuery) {
		LambdaQueryWrapper<SysDictItem> wrapper = Wrappers.<SysDictItem>lambdaQuery()
				.eq(dictItemQuery.getDictId() != null, SysDictItem::getDictId, dictItemQuery.getDictId())
				.orderByAsc(SysDictItem::getSortOrder);
		Page<SysDictItem> pageInfo = dictItemMapper.selectPage(Page.of(dictItemQuery.getPageNum(), dictItemQuery.getPageSize()), wrapper);
		return DictItemConvert.INSTANCE.convert(pageInfo);
	}
	
	@Override
	public Boolean addDictItem(DictItemDTO dictItemDTO) {
		return dictItemMapper.insert(DictItemConvert.INSTANCE.convert(dictItemDTO)) > 0;
	}
	
	@Override
	public Boolean updateDictItem(DictItemDTO dictItemDTO) {
		SysDict sysDict = dictMapper.selectById(dictItemDTO.getDictId());
		if (DictTypeEnum.SYSTEM.getType().equals(sysDict.getSystemFlag())) {
			throw new BaseException("系统内置字典，不可修改!");
		}
		return dictItemMapper.updateById(DictItemConvert.INSTANCE.convert(dictItemDTO)) > 0;
	}

	@Override
	public DictItemDTO findById(Long id) {
		return DictItemConvert.INSTANCE.convert(dictItemMapper.selectById(id));
	}

	@Override
	public List<DictItemDTO> findAll() {
		return DictItemConvert.INSTANCE.convertList(dictItemMapper.selectList(Wrappers.emptyWrapper()));
	}

	@Override
	public Boolean deleteDictItem(Long id) {
		SysDictItem item = dictItemMapper.selectById(id);
		SysDict sysDict = dictMapper.selectById(item.getDictId());
		if (DictTypeEnum.SYSTEM.getType().equals(sysDict.getSystemFlag())) {
			throw new BaseException("系统内置字典，不可删除!");
		}
		return dictItemMapper.deleteById(id) > 0;
	}

	/**
	 * 校验字典项编码是否已经被使用 新增且编码被使用、修改且编码被别的字典项使用 true 其他条件下返回false
	 * @return true or false
	 */
	@Override
	public Boolean itemExistsByCode(DictItemExistsDTO dictItemExistsDTO) {
		// 查询此字典下 该编码是否已经使用
		Boolean existsDictItem = existsDictItem(dictItemExistsDTO);
		// 如果已经被使用 判断此次是否允许操作
		if (existsDictItem) {
			if (dictItemExistsDTO.getId() == null) {
				// 如果是新增 则不可以新增
				return Boolean.TRUE;
			}
			else {
				SysDictItem sysDictItem = dictItemMapper.selectById(dictItemExistsDTO.getId());
				// 如果是修改 判断id是否和使用此编码的字典项相同
				return !(dictItemExistsDTO.getId().equals(sysDictItem.getId()));
			}
		}
		return Boolean.FALSE;
	}

	private Boolean existsDictItem(DictItemExistsDTO dictItemExistsDTO) {
		SysDictItem sysDictItem = dictItemMapper.selectOne(Wrappers.<SysDictItem>lambdaQuery()
				.eq(SysDictItem::getDictId, dictItemExistsDTO.getDictId())
				.eq(SysDictItem::getValue, dictItemExistsDTO.getValue())
				.last("limit 1"));
		return Objects.nonNull(sysDictItem);
	}
}